package com.breeze.toolkit.util;

import com.breeze.toolkit.retrofit.APIBaseResponse;
import com.google.gson.Gson;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by john on 2016/8/23.
 */
public class APIUtil {
	private static final String HMAC_SHA1 = "HmacSHA1";

	private APIUtil() {}

	public static String genMD5String(String value) {
		try {
			MessageDigest digester = MessageDigest.getInstance("MD5");
			digester.update(value.getBytes());
			byte[] b = digester.digest();

			StringBuilder buf = new StringBuilder("");
			for (int i : b) {
				if (i < 0) {
					i += 256;
				}

				if (i < 16) {
					buf.append("0");
				}
				buf.append(Integer.toHexString(i));
			}

			return buf.toString().toUpperCase();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static String genHMACSHA1String(byte[] b) {
		StringBuilder buf = new StringBuilder("");
		for (int i : b) {
			if (i < 0) {
				i += 256;
			}

			if (i < 16) {
				buf.append("0");
			}
			buf.append(Integer.toHexString(i));
		}

		return buf.toString().toUpperCase();
	}

	private static byte[] getHMacSHA1(String src)
			throws NoSuchAlgorithmException, UnsupportedEncodingException,
			InvalidKeyException {
		Mac mac = Mac.getInstance(HMAC_SHA1);
		SecretKeySpec secret = new SecretKeySpec(
				ConstantsUtil.APP_SECRET.getBytes("UTF-8"), mac.getAlgorithm());
		mac.init(secret);
		return mac.doFinal(src.getBytes());
	}

	public static String genSignString(Map<String, Object> map) {
		Set<String> keySet = map.keySet();
		if (!keySet.isEmpty()) {
			List<String> keyList = new ArrayList<>();
			for (String key : keySet) {
				keyList.add(key);
			}

			if (keyList.size() > 1) {
				Collections.sort(keyList, new Comparator<String>() {
					@Override
					public int compare(String lhs, String rhs) {
						return lhs.compareTo(rhs);
					}
				});
			}

			StringBuilder sBuilder = new StringBuilder();
			for (String key : keyList) {
				sBuilder.append(key).append(map.get(key));
			}

			LogUtil.i("before sha1 : " + sBuilder.toString());
			try {
				String sign = genHMACSHA1String(getHMacSHA1(sBuilder.toString()));
				LogUtil.i("after sha1 : " + sign);
				return sign;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return null;
	}

	public static <T> Map<String, T> getSignOrQueryMap(String[] keys, T[] values) {
		Map<String, T> map = new HashMap<>();

		if (keys.length != values.length) {
			LogUtil.e("key & value's length does not match");
		} else {
			int i = 0;
			for (String key : keys) {
				map.put(key, values[i]);
				++i;
			}
		}

		return map;
	}

	public static APIBaseResponse getResponseData(String result, Class<APIBaseResponse> clazz) {
		try {
			return new Gson().fromJson(result, clazz);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
